////////////////////////////////////////////////
//	File			:	"ObjectManager.cpp"
//
//	Author			:	Steven Seufert (SMS)
//	Based in part on: the CSGD_ObjectManager written by David Brown
//			
//	Last Modified	:	January 14, 2012
//
//	Purpose			:	To implement all functionality for the object manager singleton class
/////////////////////////////////////////////////
#include "ObjectManager.h"
#include "Globals.h"
#include "CSpellBase.h"
#include <string>
using std::string;

// initialize the instance pointer to the singleton to NULL
//CObjectManager* CObjectManager::sm_Instance = NULL;

CObjectManager::CObjectManager()
{
	/*for (int group = 0; group < NUM_OM_GROUPS; group++)
	{
		m_vObjectList[group].push_back(NULL);
	}

	for (int layer = 0; layer < RL_NUM_RENDER_LAYERS; layer++)
	{
		m_vRenderList[layer].push_back(NULL);
	}*/
}

// call the instance to our singleton
CObjectManager* CObjectManager::GetInstance(void)
{
	//	Lazy instantiation
	static CObjectManager instance;
	return &instance;
	//// if the object manager hasn't been initialzed yet
	//if (NULL == sm_Instance)
	//{
	//	sm_Instance = new CObjectManager();
	//}

	//// return with the pointer to the object manager
	//return sm_Instance;
}

// delete the instance of our singleton
void CObjectManager::DeleteInstance(void)
{
	//// if the object manager currently has an instance
	//if (sm_Instance)
	//{
	//	// delete this instance
	//	delete sm_Instance;
	//	// reset the instance pointer to null
	//	sm_Instance = NULL;
	//}

	// do nothing if the manager doesn't yet have an instance
}

///////////////////////////////////////////////////
//	Function	:	"UpdateObjects"
//	
//	Last Modified:	February 25, 2012
//
//	Input		:	fElapsedTime	-	the amount of time in seconds that has passed since the last frame
//					group			-	combination of flags for which specific groups you want to update 
//										(OMF_PLAYER, OMF_ENEMY, OMF_SPELL, OMF_ENVOBJECT, OMF_ALL)
//
//	Return		:	none
//
//	Purpose		:	To update all the objects in a specific group (or all objects)
//////////////////////////////////////////////////
void CObjectManager::UpdateObjects(float fElapsedTime, unsigned int group)
{
	// if the user wants to update all objects in the manager
	if (group & OMF_ALL)
	{
		unsigned int playerSize = GetSize(OMF_PLAYER);
		unsigned int enemySize = GetSize(OMF_ENEMY);
		unsigned int spellSize = GetSize(OMF_SPELL);
		unsigned int envObjSize = GetSize(OMF_ENVOBJECT);
		
		// update all the player objects
		if (m_vObjectList[OMG_PLAYERS].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < playerSize; vectorIndex++)
			{
				m_vObjectList[OMG_PLAYERS][vectorIndex]->Update(fElapsedTime);
			}
		}

		// update all the enemy objects
		if (m_vObjectList[OMG_ENEMIES].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < enemySize; vectorIndex++)
			{
				m_vObjectList[OMG_ENEMIES][vectorIndex]->Update(fElapsedTime);
			}
		}

		// update all the spell objects
		if (m_vObjectList[OMG_SPELLS].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < spellSize; vectorIndex++)
			{
				m_vObjectList[OMG_SPELLS][vectorIndex]->Update(fElapsedTime);
			}
		}

		// update all the environmental objects
		if (m_vObjectList[OMG_ENVOBJECTS].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < envObjSize; vectorIndex++)
			{
				m_vObjectList[OMG_ENVOBJECTS][vectorIndex]->Update(fElapsedTime);
			}
		}
		// exit now or you'll update go on to update all the objects a second time
		return;
	}

	// if the user wants to update all the objects in the Player group
	if (group & OMF_PLAYER)
	{
		unsigned int playerSize = GetSize(OMF_PLAYER);
		
		if (m_vObjectList[OMG_PLAYERS].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < playerSize; vectorIndex++)
			{
				m_vObjectList[OMG_PLAYERS][vectorIndex]->Update(fElapsedTime);
			}
		}
	}

	// if the user wants to update all the objects in the ENEMY group
	if (group & OMF_ENEMY)
	{
		unsigned int enemySize = GetSize(OMF_ENEMY);

		if (m_vObjectList[OMG_ENEMIES].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < enemySize; vectorIndex++)
			{
				m_vObjectList[OMG_ENEMIES][vectorIndex]->Update(fElapsedTime);
			}
		}
	}

	// if the user wants to update all the objects in the SPELL group
	if (group & OMF_SPELL)
	{
		unsigned int spellSize = GetSize(OMF_SPELL);
		
		if (m_vObjectList[OMG_SPELLS].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < spellSize; vectorIndex++)
			{
				m_vObjectList[OMG_SPELLS][vectorIndex]->Update(fElapsedTime);
			}
		}

	}

	// if the user wants to update all the objects in the Environment Objects group
	if (group & OMF_ENVOBJECT)
	{
		unsigned int envObjSize = GetSize(OMF_ENVOBJECT);
		
		if (m_vObjectList[OMG_ENVOBJECTS].size() > 0)
		{
			for (unsigned int vectorIndex = 0; vectorIndex < envObjSize; vectorIndex++)
			{
				m_vObjectList[OMG_ENVOBJECTS][vectorIndex]->Update(fElapsedTime);
			}
		}
	}
}

///////////////////////////////////////////////////
//	Function	:	"RenderObjectsByLayer"
//	
//	Last Modified:	February 25, 2012
//
//	Input		:	none
//										
//	Return		:	none
//
//	Purpose		:	To render all the objects in ascending layer order
//////////////////////////////////////////////////
void CObjectManager::RenderObjectsByLayer()
{
	for (unsigned int thisLayer = 0; thisLayer < RL_NUM_RENDER_LAYERS; thisLayer++)
	{
		unsigned int groupSize = GetSizeOfLayer(thisLayer);
		if (m_vRenderList[thisLayer].size() > 0)
		{
			for (unsigned int thisElement = 0; thisElement < groupSize; thisElement++)
			{
				m_vRenderList[thisLayer][thisElement]->Render();
			}
		}
	}
}

///////////////////////////////////////////////////
//	Function	:	"RenderObjects"
//	
//	Last Modified:	January 14, 2012
//
//	Input		:	group			-	combination of flags for which specific groups you want to update 
//										(OMF_PLAYER, OMF_ENEMY, OMF_SPELL, OMF_ENVOBJECT, OMF_ALL)
//										
//	Return		:	none
//
//	Purpose		:	To render all the objects in a specific group (or all objects)
//////////////////////////////////////////////////
void CObjectManager::RenderObjectsByGroup(unsigned int group)
{
	// if the user wants to render all objects in the manager
	if (group & OMF_ALL)
	{
		unsigned int playerSize = GetSize(OMF_PLAYER);
		unsigned int enemySize = GetSize(OMF_ENEMY);
		unsigned int spellSize = GetSize(OMF_SPELL);
		unsigned int envObjSize = GetSize(OMF_ENVOBJECT);
		
		// render all the player objects
		for (unsigned int vectorIndex = 0; vectorIndex < playerSize; vectorIndex++)
		{
			m_vObjectList[OMG_PLAYERS][vectorIndex]->Render();
		}

		// render all the enemy objects
		for (unsigned int vectorIndex = 0; vectorIndex < enemySize; vectorIndex++)
		{
			m_vObjectList[OMG_ENEMIES][vectorIndex]->Render();
		}

		// render all the spell objects
		for (unsigned int vectorIndex = 0; vectorIndex < spellSize; vectorIndex++)
		{
			m_vObjectList[OMG_SPELLS][vectorIndex]->Render();
		}

		// render all the environmental objects
		for (unsigned int vectorIndex = 0; vectorIndex < envObjSize; vectorIndex++)
		{
			m_vObjectList[OMG_ENVOBJECTS][vectorIndex]->Render();
		}
		// exit now or you'll update go on to update all the objects a second time
		return;
	}

	// if the user wants to render all the objects in the Player group
	if (group & OMF_PLAYER)
	{
		unsigned int playerSize = GetSize(OMF_PLAYER);
		
		for (unsigned int vectorIndex = 0; vectorIndex < playerSize; vectorIndex++)
		{
			m_vObjectList[OMG_PLAYERS][vectorIndex]->Render();
		}
	}

	// if the user wants to render all the objects in the ENEMY group
	if (group & OMF_ENEMY)
	{
		unsigned int enemySize = GetSize(OMF_ENEMY);

		for (unsigned int vectorIndex = 0; vectorIndex < enemySize; vectorIndex++)
		{
			m_vObjectList[OMG_ENEMIES][vectorIndex]->Render();
		}
	}

	// if the user wants to render all the objects in the SPELL group
	if (group & OMF_SPELL)
	{
		unsigned int spellSize = GetSize(OMF_SPELL);
		
		for (unsigned int vectorIndex = 0; vectorIndex < spellSize; vectorIndex++)
		{
			m_vObjectList[OMG_SPELLS][vectorIndex]->Render();
		}

	}

	// if the user wants to render all the objects in the Environment Objects group
	if (group & OMF_ENVOBJECT)
	{
		unsigned int envObjSize = GetSize(OMF_ENVOBJECT);
		
		for (unsigned int vectorIndex = 0; vectorIndex < envObjSize; vectorIndex++)
		{
			m_vObjectList[OMG_ENVOBJECTS][vectorIndex]->Render();
		}
	}
}

///////////////////////////////////////////////////
//	Function	:	"AddObject"
//	
//	Last Modified:	February 25, 2012
//
//	Input		:	pObject			-	a pointer to the object you want to add to the object manager
//					group			-	flag for which specific group you want to place the object in
//										(OMF_PLAYER, OMF_ENEMY, OMF_SPELL, OMF_ENVOBJECT)
//					renderLayer		-	the render layer at which you wish the object to be rendered
//										
//	Return		:	none
//
//	Purpose		:	To add an object to a specific group 
//
//	Notes		:	The function will exit without adding the object if the flag OMF_ALL is used.
//					A specified group must be sent to actually add the object
//					The function will exit if a null pointer is passed
//					Adding more than one flag may result in the object being added to an unwanted group
//////////////////////////////////////////////////
void CObjectManager::AddObject(IBaseInterface* pObject, unsigned int group, int renderLayer)
{
	// Is this a valid pointer?
	if (NULL == pObject)
		return;

	
	// Don't add duplicates to the object manager
//	for (unsigned int thisGroup = 0; thisGroup < NUM_OM_GROUPS; thisGroup++)
//	{
//		unsigned int groupSize = GetSize(thisGroup);
//		for (unsigned int index = 0; index < groupSize; index++)
//		{
//			if (m_vObjectList[thisGroup][index] == pObject)
//			{
//#ifdef _DEBUG	
//				char buffer [256];
//				sprintf_s(buffer, _countof(buffer), "Duplicate Object of type %i passed to Object Manager's AddObject().", pObject->GetType());
//				MessageBox(0, buffer, "Duplicate Object Error", MB_OK);		
//#endif
//				return;	// break out of AddObject()
//			}
//				
//		}
//	}

	// exit if the user accidentally tried to add the object to every group
	if (group == OMF_ALL)
	{
		cout << "You attempted to add an object to the ALL group. \n";
		return;
	}
	/* add the object to the object's group */
	 
	if (group & OMF_PLAYER)
	{
		m_vObjectList[OMG_PLAYERS].push_back(pObject);

		// add a reference to this object
		pObject->AddRef();
	}
	else if (group & OMF_ENEMY)
	{
		m_vObjectList[OMG_ENEMIES].push_back(pObject);

		// add a reference to this object
		pObject->AddRef();
	}
	else if (group & OMF_SPELL)
	{
		m_vObjectList[OMG_SPELLS].push_back(pObject);

		// add a reference to this object
		pObject->AddRef();
	}
	else if (group & OMF_ENVOBJECT)
	{
		m_vObjectList[OMG_ENVOBJECTS].push_back(pObject);

		// add a reference to this object
		pObject->AddRef();
	}

	// Add to the Render Layer vector
	m_vRenderList[renderLayer].push_back(pObject);
	pObject->AddRef();
	
}

///////////////////////////////////////////////////
//	Function	:	"RemoveObject"
//	
//	Last Modified:	January 14, 2012
//
//	Input		:	pObject			-	a pointer to the object you want to remove to the from the object manager
//										
//	Return		:	none
//
//	Purpose		:	To remove an object from the object manager
//////////////////////////////////////////////////
void CObjectManager::RemoveObject(IBaseInterface* pObject)
{
	// Is this even a valid pointer?
	if (NULL == pObject)
		return;

	unsigned int objectType = pObject->GetOMGroupID();

	switch (objectType)
	{
	case OMG_PLAYERS:
		{
			for (vector<IBaseInterface*>::iterator iter = m_vObjectList[OMG_PLAYERS].begin(); iter != m_vObjectList[OMG_PLAYERS].end(); iter++)
			{
				// if this is the object we are looking for.
				if ((*iter) == pObject)
				{
					// Remove my reference to this object.
					(*iter)->Release();

					// Remove the object from the list
					iter = m_vObjectList[OMG_PLAYERS].erase(iter);
					break;
				}
			}
		}
		break;

	case OMG_ENEMIES:
		{
			for (vector<IBaseInterface*>::iterator iter = m_vObjectList[OMG_ENEMIES].begin(); iter != m_vObjectList[OMG_ENEMIES].end(); iter++)
			{
				// if this is the object we are looking for.
				if ((*iter) == pObject)
				{
					// Remove my reference to this object.
					(*iter)->Release();

					// Remove the object from the list
					iter = m_vObjectList[OMG_ENEMIES].erase(iter);
					break;
				}
			}
		}
		break;

	case OMG_SPELLS:
		{
			for (vector<IBaseInterface*>::iterator iter = m_vObjectList[OMG_SPELLS].begin(); iter != m_vObjectList[OMG_SPELLS].end(); iter++)
			{
				// if this is the object we are looking for.
				if ((*iter) == pObject)
				{
					// Remove my reference to this object.
					(*iter)->Release();

					// Remove the object from the list
					iter = m_vObjectList[OMG_SPELLS].erase(iter);
					break;
				}
			}
		}
		break;

	case OMG_ENVOBJECTS:
		{
			for (vector<IBaseInterface*>::iterator iter = m_vObjectList[OMG_ENVOBJECTS].begin(); iter != m_vObjectList[OMG_ENVOBJECTS].end(); iter++)
			{
				// if this is the object we are looking for.
				if ((*iter) == pObject)
				{
					// Remove my reference to this object.
					(*iter)->Release();

					// Remove the object from the list
					iter = m_vObjectList[OMG_ENVOBJECTS].erase(iter);
					break;
				}
			}
		}
		break;
	} // end switch
	
	// Remove the object from the render list as well
	for (unsigned int thisLayer = 0; thisLayer < RL_NUM_RENDER_LAYERS; thisLayer++)
	{
		for (vector<IBaseInterface*>::iterator iter = m_vRenderList[thisLayer].begin(); iter != m_vRenderList[thisLayer].end(); iter++)
		{
			if ((*iter) == pObject)
			{
				(*iter)->Release();

				iter = m_vRenderList[thisLayer].erase(iter);
				break;
			}
		}
	}
}

///////////////////////////////////////////////////
//	Function	:	"GetSize"
//	
//	Last Modified:	January 14, 2012
//
//	Input		:	group			-	combination of flags for which specific groups you want to query for size
//										(OMF_PLAYER, OMF_ENEMY, OMF_SPELL, OMF_ENVOBJECT, OMF_ALL)
//										
//	Return		:	the total number of objects in the object manager group(s)
//
//	Purpose		:	To return the total number of objects in the object manager group(s)
//////////////////////////////////////////////////
int CObjectManager::GetSize(unsigned int group) const
{
	int size = 0;

	if (group & OMF_ALL)
	{
		size += m_vObjectList[OMG_PLAYERS].size();
		size += m_vObjectList[OMG_ENEMIES].size();
		size += m_vObjectList[OMG_SPELLS].size();
		size += m_vObjectList[OMG_ENVOBJECTS].size();

		// return with the size of the object manager's total object count
		return size;
	}

	if (group & OMF_PLAYER)
	{
		size += m_vObjectList[OMG_PLAYERS].size();
	}

	if (group & OMF_ENEMY)
	{
		size += m_vObjectList[OMG_ENEMIES].size();
	}

	if (group & OMF_SPELL)
	{
		size += m_vObjectList[OMG_SPELLS].size();
	}

	if (group & OMF_ENVOBJECT)
	{
		size += m_vObjectList[OMG_ENVOBJECTS].size();
	}

	return size;
}

///////////////////////////////////////////////////
//	Function	:	"GetSizeOfLayer"
//	
//	Last Modified:	February 25, 2012
//
//	Input		:	layer			-	the layer whose size you wish to obtain
//										Pass NUM_RENDER_LAYERS to get the number of all render objects
//										
//	Return		:	the total number of objects in the object manager render layer
//
//	Purpose		:	To return the total number of objects in the object manager render layer
//////////////////////////////////////////////////
int CObjectManager::GetSizeOfLayer(unsigned int layer) const
{
	int size = 0;

	if (RL_NUM_RENDER_LAYERS == layer)
	{
		for (int index = 0; index < RL_NUM_RENDER_LAYERS; index++)
		{
			size += m_vRenderList[index].size();
		}
		return size;
	}

	switch (layer)
	{
	case RL_WORLD_TILES:
		{
			size = m_vRenderList[RL_WORLD_TILES].size();
		}
		break;

	case RL_RESERVED1:
		{
			size = m_vRenderList[RL_RESERVED1].size();
		}
		break;

	case RL_BOTTOM_EFFECTS:
		{
			size = m_vRenderList[RL_BOTTOM_EFFECTS].size();
		}
		break;

	case RL_MAIN:
		{
			size = m_vRenderList[RL_MAIN].size();
		}
		break;

	case RL_TOP_EFFECTS:
		{
			size = m_vRenderList[RL_TOP_EFFECTS].size();
		}
		break;

	case RL_RESERVED5:
		{
			size = m_vRenderList[RL_RESERVED5].size();
		}
		break;

	case RL_HUD:
		{
			size = m_vRenderList[RL_HUD].size();
		}
		break;

	case RL_HUD2:
		{
			size = m_vRenderList[RL_HUD2].size();
		}
		break;

	case RL_CURSOR:
		{
			size = m_vRenderList[RL_CURSOR].size();
		}
		break;

	case RL_RESERVED9:
		{
			size = m_vRenderList[RL_RESERVED9].size();
		}
		break;

#ifdef _DEBUG
	default:
		{
			char buffer [256];
			sprintf_s(buffer, _countof(buffer), "Unknown layer %i passed to Object Manager's GetSizeOfLayer().\nDefault case in switch statement reached.", layer);
			MessageBox(0, buffer, "Layer Size Error", MB_OK);
		}
		break;
#endif
	}

	return size;
}

///////////////////////////////////////////////////
//	Function	:	"RemoveAllObjects"
//	
//	Last Modified:	February 25, 2012
//
//	Input		:	none
//										
//	Return		:	none
//
//	Purpose		:	Removes all objects in the entire object manager
//////////////////////////////////////////////////
void CObjectManager::RemoveAllObjects(void)
{
	unsigned int playerSize = GetSize(OMF_PLAYER);
	unsigned int enemySize = GetSize(OMF_ENEMY);
	unsigned int spellSize = GetSize(OMF_SPELL);
	unsigned int envobjectSize = GetSize(OMF_ENVOBJECT);

	// release all player objects
	for (unsigned int index = 0; index < playerSize; index++)
	{
		m_vObjectList[OMG_PLAYERS][index]->Release();
	}
	// release all enemy objects
	for (unsigned int index = 0; index < enemySize; index++)
	{
		m_vObjectList[OMG_ENEMIES][index]->Release();
	}
	// release all spells
	for (unsigned int index = 0; index < spellSize; index++)
	{
		m_vObjectList[OMG_SPELLS][index]->Release();
	}
	// release all environmental objects
	for (unsigned int index = 0; index < envobjectSize; index++)
	{
		m_vObjectList[OMG_ENVOBJECTS][index]->Release();
	}

	//	Collapse the vectors
	for (unsigned int index = 0; index < NUM_OM_GROUPS; index++)
	{
		m_vObjectList[index].clear();
	}

	// Remove the objects from the Render List
	for (unsigned int thisLayer = 0; thisLayer < RL_NUM_RENDER_LAYERS; thisLayer++)
	{
		unsigned int groupSize = GetSizeOfLayer(thisLayer);
		if (m_vRenderList[thisLayer].size() > 0)
		{
			for (unsigned int thisElement = 0; thisElement < groupSize; thisElement++)
			{
				m_vRenderList[thisLayer][thisElement]->Release();
			}
		}
	}

	// clear the render list
	for (unsigned int layer = 0; layer < RL_NUM_RENDER_LAYERS; layer++)
	{
		m_vRenderList[layer].clear();
	}
}

///////////////////////////////////////////////////
//	Function	:	"CheckCollisions"
//	
//	Last Modified:	January 14, 2012
//
//	Input		:	groupOne		-	the specific group of objects you want to check against group two's objects
//					groupTwo		-	the specific group of objects you want to groupOne to check against
//										(OMF_PLAYER, OMF_ENEMY, OMF_SPELL, OMF_ENVOBJECT)
//										
//	Return		:	none
//
//	Purpose		:	To run every object's CheckCollision() in group one against every object in group two
//
//	Notes		:	This does not check collisions if you pass OMF_ALL to either group
//////////////////////////////////////////////////
void CObjectManager::CheckCollisions(unsigned int groupOne, unsigned int groupTwo)
{
	// There is no ALL!
	if ((groupOne & OMF_ALL) || (groupTwo & OMF_ALL))
		return;
}

///////////////////////////////////////////////////
//	Function	:	"CheckAllCollisions"
//	
//	Last Modified:	January 14, 2012
//										
//	Return		:	none
//
//	Purpose		:	To check collisions of each object against all other objects
//
// Notes		:	Environmental objects are not checked against environmental objects because they don't move
//////////////////////////////////////////////////
void CObjectManager::CheckAllCollisions()
{
	unsigned int playerSize = GetSize(OMF_PLAYER);
	unsigned int enemySize = GetSize(OMF_ENEMY);
	unsigned int spellSize = GetSize(OMF_SPELL);
	unsigned int envobjectSize = GetSize(OMF_ENVOBJECT);

	/* players against players */
	// for each object in the first group
	for (unsigned int i = 0; i < playerSize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < playerSize; j++)
		{
			// make sure the object isn't checking against itself
			if (m_vObjectList[OMG_PLAYERS][i] != m_vObjectList[OMG_PLAYERS][j] )
			{
				if(m_vObjectList[OMG_PLAYERS][i]->CheckCollision(m_vObjectList[OMG_PLAYERS][j]))
					break;
			}
		}
	}

	/* players against enemies */
	// for each object in the first group
	for (unsigned int i = 0; i < playerSize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < enemySize; j++)
		{
			if(m_vObjectList[OMG_PLAYERS][i]->CheckCollision(m_vObjectList[OMG_ENEMIES][j]))
				break;
		}
	}

	/* players against spells */
	// for each object in the first group
	for (unsigned int i = 0; i < playerSize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < spellSize; j++)
		{
			if(m_vObjectList[OMG_PLAYERS][i]->CheckCollision(m_vObjectList[OMG_SPELLS][j]))
				break;
		}
	}

	/* players against environmental objects */
	// for each object in the first group
	for (unsigned int i = 0; i < playerSize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < envobjectSize; j++)
		{
			if(m_vObjectList[OMG_PLAYERS][i]->CheckCollision(m_vObjectList[OMG_ENVOBJECTS][j]))
				break;
		}
	}

	/* enemies against enemies */
	// for each object in the first group
	for (unsigned int i = 0; i < enemySize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < enemySize; j++)
		{
			// make sure the object isn't checking against itself
			if (m_vObjectList[OMG_ENEMIES][i] != m_vObjectList[OMG_ENEMIES][j] )
			{
				if(m_vObjectList[OMG_ENEMIES][i]->CheckCollision(m_vObjectList[OMG_ENEMIES][j]))
					break;
			}
		}
	}

	/* enemies against spells */
	// for each object in the first group
	for (unsigned int i = 0; i < enemySize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < spellSize; j++)
		{
			if(m_vObjectList[OMG_ENEMIES][i]->CheckCollision(m_vObjectList[OMG_SPELLS][j]))
				break;
		}
	}

	/* enemies against environmental objects */
	// for each object in the first group
	for (unsigned int i = 0; i < enemySize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < envobjectSize; j++)
		{
			if(m_vObjectList[OMG_ENEMIES][i]->CheckCollision(m_vObjectList[OMG_ENVOBJECTS][j]))
				break;
		}
	}

	/* spells against spells */
	// for each object in the first group
	for (unsigned int i = 0; i < spellSize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < spellSize; j++)
		{
			// make sure the object isn't checking against itself
			if (m_vObjectList[OMG_SPELLS][i] != m_vObjectList[OMG_SPELLS][j] )
			{
				if(m_vObjectList[OMG_SPELLS][i]->CheckCollision(m_vObjectList[OMG_SPELLS][j]))
					break;
			}
		}
	}

	/* spells against environmental objects */
	// for each object in the first group
	for (unsigned int i = 0; i < spellSize; i++)
	{
		// check against each object in the second group
		for (unsigned int j = 0; j < envobjectSize; j++)
		{
			if(m_vObjectList[OMG_SPELLS][i]->CheckCollision(m_vObjectList[OMG_ENVOBJECTS][j]))
				break;
		}
	}

	// Environmental objects are not checked against environmental objects because they don't move
}

///////////////////////////////////////////////////
//	Function	:	"PrintObjectsToConsole"
//	
//	Last Modified:	January 14, 2012
//
//	Input		:	group			-	combination of flags for which specific groups you want to query for size
//										(OMF_PLAYER, OMF_ENEMY, OMF_SPELL, OMF_ENVOBJECT, OMF_ALL)
//										
//	Return		:	none
//
//	Purpose		:	Prints the object class type IDs for each object in the manager to the console
//////////////////////////////////////////////////
void CObjectManager::PrintObjectsToConsole(unsigned int group)
{
	unsigned int playerSize = GetSize(OMF_PLAYER);
	unsigned int enemySize = GetSize(OMF_ENEMY);
	unsigned int spellSize = GetSize(OMF_SPELL);
	unsigned int envobjectSize = GetSize(OMF_ENVOBJECT);

	cout << "///////////////////////////////////////////////// \n";
	cout << "Total Objects in manager: " << GetSize(OMF_ALL);
	cout << "\n\nPlayer Objects in the Object Manager: " << playerSize << "\n";
	for (unsigned int i = 0; i < playerSize; i++)
	{
		cout << "Player \n";
	}

	cout << "\n\nEnemy Objects in the Object Manager: " << enemySize << "\n";
	for (unsigned int i=0; i < enemySize; i++)
	{
		cout << m_vObjectList[OMG_ENEMIES][i]->GetEnemyName() << endl;
	}

	cout << "\n\nSpell Objects in the Object Manager: " << spellSize << "\n";
	for (unsigned int i=0; i < spellSize; i++)
	{
		cout << m_vObjectList[OMG_SPELLS][i]->GetSpellName() << endl;	
	}

	cout << "\n\nEnvironmental Objects in the Object Manager: " << envobjectSize << "\n";
	for (unsigned int i=0; i < envobjectSize; i++)
	{
		cout << "Environmental object \n";

	}
}